Implement interesting firmware workaround for x05 models to force lap
authorrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Sun, 30 Apr 2006 01:26:40 +0000 (01:26 +0000)
committerrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Sun, 30 Apr 2006 01:26:40 +0000 (01:26 +0000)
closure  so that stored tracks can be retrieved.

Note that this forces the widening of the command array to two bytes -
it's always technically _been_ two byts, but we've never had a command
# > 127 before. This does have the potential to expose naughtiness if
we've missed any endian swaps...

gpsbabel/jeeps/gpsapp.c
gpsbabel/jeeps/gpsapp.h
gpsbabel/jeeps/gpsprot.c
gpsbabel/jeeps/gpsprot.h
gpsbabel/jeeps/gpsusbcommon.c

index 31e45b0df31ad460264e013268f8beafbe74c640..80b789a38f618ae0189dc5e535da218c55aa4992 100644 (file)
@@ -417,7 +417,9 @@ static void GPS_A001(GPS_PPacket packet)
                case 800:
                    gps_pvt_transfer = pA800;
                    break;
-
+               case 1000:
+                   gps_run_transfer = pA1000;
+                   break;
            }
            break;
 
@@ -3417,8 +3419,46 @@ int32 GPS_A300_Get(const char *port, GPS_PTrack **trk)
     return ret;
 }
 
+/*
+ * This is to get around a problem with the x305 sporting units.
+ * The unit will not "finalize" a track unless the operator manually
+ * does it from the pushbutton panel OR until the device has gone through
+ * a 'get runs' cycle.  Garmin's Training Center, of course, does this
+ * because it actually uses that data.   Here we just go through the 
+ * mechanics of building and sending the requests and then throwing away
+ * all the data in order to finalize that.
+ *
+ * Hopefully, this won't be needed forever.
+ */
+drain_run_cmd(gpsdevh *fd)
+{
+    GPS_PPacket tra;
+    GPS_PPacket rec;
+    static UC data[2];
 
+    if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New()))
+       return MEMORY_ERROR;
 
+    GPS_Util_Put_Short(data,
+                      COMMAND_ID[gps_device_command].Cmnd_Transfer_Runs);
+    GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data,
+                   data,2);
+
+    if(!GPS_Write_Packet(fd,tra))
+       return gps_errno;
+    if(!GPS_Get_Ack(fd, &tra, &rec))
+       return gps_errno;
+
+    for(;;) {
+       if(!GPS_Packet_Read(fd, &rec))
+           return gps_errno;
+       if(!GPS_Send_Ack(fd, &tra, &rec))
+           return gps_errno;
+       if(rec->type == LINK_ID[gps_link_type].Pid_Xfer_Cmplt) {
+           break;
+       }
+    }
+}
 
 /* @func GPS_A301_Get ******************************************************
 **
@@ -3451,6 +3491,10 @@ int32 GPS_A301_Get(const char *port, GPS_PTrack **trk)
     if(!GPS_Device_On(port, &fd))
        return gps_errno;
 
+    if ((gps_trk_type == pD304) && gps_run_transfer) {
+       drain_run_cmd(fd);
+    }
+
     if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New()))
        return MEMORY_ERROR;
 
@@ -6130,7 +6174,7 @@ void GPS_D906_Get(GPS_PPacket packet, GPS_PLap_Data *Lap)
  */
 
 const char *
-Get_Pkt_Type(unsigned char p, unsigned char d0, const char **xinfo)
+Get_Pkt_Type(unsigned char p, unsigned short d0, const char **xinfo)
 {
        *xinfo = NULL;
 #define LT LINK_ID[gps_link_type]
@@ -6152,6 +6196,11 @@ Get_Pkt_Type(unsigned char p, unsigned char d0, const char **xinfo)
                        case 92: *xinfo = "Flight Records"; break;
                        case 117: *xinfo = "Xfer Laps"; break;
                        case 121: *xinfo = "Xfer Categories"; break;
+                       case 450: *xinfo = "Xfer Runs"; break;
+                       case 451: *xinfo = "Xfer Workouts"; break;
+                       case 452: *xinfo = "Xfer Wkt Occurrences"; break;
+                       case 453: *xinfo = "Xfer User Profile "; break;
+                       case 454: *xinfo = "Xfer Wkt Limits"; break;
                        default: *xinfo = "Unknown";
                }
                return "CMDDAT";
index 38a628f32aa8521b8fef2c9b95006fef9c991b53..e12208e4babe82f561df463a7ebb52b4f8a67331 100644 (file)
@@ -57,7 +57,7 @@ int32  GPS_A800_Off(const char *port, gpsdevh **fd);
 int32  GPS_A800_Get(gpsdevh **fd, GPS_PPvt_Data *packet);
 void   GPS_D800_Get(GPS_PPacket packet, GPS_PPvt_Data *pvt);
 
-const char * Get_Pkt_Type(unsigned char p, unsigned char d0, const char **xinfo);
+const char * Get_Pkt_Type(unsigned char p, unsigned short d0, const char **xinfo);
 
 
 #endif
index fabdfd89a464265182499049ec07f833bcf6283d..63976d995f331471c6dd4398762ffc78e542107d 100644 (file)
@@ -37,7 +37,7 @@ static int32 gps_n_tag_unknown = 0;
 struct COMMANDDATA COMMAND_ID[2]=
 {
     {
-       0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x31,0x32,92,117,121
+       0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x31,0x32,92,117,121,450
     }
     ,
     {
index f9542799d494388c7d81a59891a6a5b947af338c..05ff718578e8a8bdcb841ea4b960551725ee0c3e 100644 (file)
@@ -53,20 +53,21 @@ int32 gps_device_command;
 
 struct COMMANDDATA
 {
-    UC Cmnd_Abort_Transfer;
-    UC Cmnd_Transfer_Alm;
-    UC Cmnd_Transfer_Posn;
-    UC Cmnd_Transfer_Prx;
-    UC Cmnd_Transfer_Rte;
-    UC Cmnd_Transfer_Time;
-    UC Cmnd_Transfer_Trk;
-    UC Cmnd_Transfer_Wpt;
-    UC Cmnd_Turn_Off_Pwr;
-    UC Cmnd_Start_Pvt_Data;
-    UC Cmnd_Stop_Pvt_Data;
-    UC Cmnd_FlightBook_Transfer;
-    UC Cmnd_Transfer_Lap;
-    UC Cmnd_Transfer_Wpt_Cats;
+    US Cmnd_Abort_Transfer;
+    US Cmnd_Transfer_Alm;
+    US Cmnd_Transfer_Posn;
+    US Cmnd_Transfer_Prx;
+    US Cmnd_Transfer_Rte;
+    US Cmnd_Transfer_Time;
+    US Cmnd_Transfer_Trk;
+    US Cmnd_Transfer_Wpt;
+    US Cmnd_Turn_Off_Pwr;
+    US Cmnd_Start_Pvt_Data;
+    US Cmnd_Stop_Pvt_Data;
+    US Cmnd_FlightBook_Transfer;
+    US Cmnd_Transfer_Lap;
+    US Cmnd_Transfer_Wpt_Cats;
+    US Cmnd_Transfer_Runs;
 }
 ;
 
@@ -138,9 +139,11 @@ int32 gps_pvt_transfer;
  * Lap Data Transfer
  */
 #define pA906 906
-
 int32 gps_lap_transfer;
 
+#define pA1000 1000
+int32 gps_run_transfer;
+
 
 
 /*
index 94e6adac011d4531602f6684c6c417cbda4907d4..4f8f395b6cd4d5e4c7306e015018de3d19e05ef5 100644 (file)
@@ -101,6 +101,7 @@ top:
        if (gps_show_bytes) {
                int i;
                const char *m1, *m2;
+               unsigned short pkttype = le_read16(&ibuf->gusb_pkt.databuf[0]);
 
                GPS_Diag("RX (%s) [%d]:", 
                        receive_state == rs_fromintr ? "intr" : "bulk", rv);
@@ -121,8 +122,7 @@ top:
                        GPS_Diag("%c", isalnum(buf[i])? buf[i] : '.');
                }
 
-               m1 = Get_Pkt_Type(ibuf->gusb_pkt.pkt_id[0], 
-                       ibuf->gusb_pkt.databuf[0], &m2);
+               m1 = Get_Pkt_Type(ibuf->gusb_pkt.pkt_id[0], pkttype, &m2);
 if ((rv == 0)  &&  (receive_state == rs_frombulk) ) {m1= "RET2INTR";m2=NULL;};
                GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : "");
        }
@@ -158,6 +158,7 @@ gusb_cmd_send(const garmin_usb_packet *opkt, size_t sz)
        rv = gusb_llops->llop_send(opkt, sz);
 
        if (gps_show_bytes) {
+               unsigned short pkttype = le_read16(&opkt->gusb_pkt.databuf[0]);
                GPS_Diag("TX [%d]:", sz);
 
                for(i=0;i<sz;i++)
@@ -166,8 +167,7 @@ gusb_cmd_send(const garmin_usb_packet *opkt, size_t sz)
                for(i=0;i<sz;i++)
                        GPS_Diag("%c", isalnum(obuf[i])? obuf[i] : '.');
 
-               m1 = Get_Pkt_Type(opkt->gusb_pkt.pkt_id[0], 
-                       opkt->gusb_pkt.databuf[0], &m2);
+               m1 = Get_Pkt_Type(opkt->gusb_pkt.pkt_id[0], pkttype, &m2);
 
                GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : "");
         }